package caronas.controller;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.view.Results;
import caronas.dao.CaronaDao;
import caronas.dao.UsuarioDao;
import caronas.infra.LoginBypass;
import caronas.modelo.Carona;
import caronas.modelo.Mapa;
import caronas.modelo.Service;
import caronas.modelo.Trajeto;
import caronas.modelo.Usuario;
import caronas.modelo.UsuarioWeb;
import caronas.util.CaronaWrapper;
import caronas.util.EmailUtils;
import caronas.util.FacebookUtils;
import caronas.util.UsuarioProxy;

@Resource
public class CaronaController {
	
	private CaronaDao dao;
	private Result result;
	private UsuarioWeb usuarioWeb;
	private FacebookUtils fbUtils;
	private EmailUtils emailUtils;
	private UsuarioDao usuarioDao;
	private final HttpServletRequest request; 
	public CaronaController(CaronaDao dao, Result result, UsuarioWeb usuarioWeb, FacebookUtils fbUtils, EmailUtils emailUtils, UsuarioDao usuarioDao, HttpServletRequest request ) {
		this.dao = dao;
		this.result = result;
		this.usuarioWeb = usuarioWeb;
        this.fbUtils = fbUtils;
        this.emailUtils = emailUtils;
        this.usuarioDao = usuarioDao;
        this.request = request;
	}
	
	@LoginBypass
	@Get @Path("/")
	public void index() {
		result.redirectTo(this).sobre();
	}
	
	@LoginBypass
	@Get @Path("/carona/sobre")
	public void sobre(){
		
	}
	
	@LoginBypass
	@Get @Path("/carona/listar") 
	public void listar() {
		List<Carona> caronaList = dao.listar(usuarioWeb.getUsuario(), request.getParameter("scope"));
		result.include("caronaList", caronaList);
	}
	
	@Get @Path("/carona/nova")
	public void nova() {
	}
	
	@Post @Path("/carona")
	public void adicionar(Carona carona, String teste) {
		carona.setUsuario(usuarioWeb.getUsuario());
		dao.adicionar(carona);
		result.redirectTo(this).listar();
	}
	
	@Put @Path("/carona/{carona.id}")
	public void atualizar(Carona carona) {
		carona.setUsuario(usuarioWeb.getUsuario());
		dao.atualizar(carona);
		result.redirectTo(this).listar();
	}
	
	@Get @Path("/carona/{id}")
	public void editar(Long id) {
		result.include("carona", dao.carregar(id));
		
	}
	
	@Post @Path("/carona/remove/{id}")
	public void remover(Long id) {
		dao.remover(id);
		result.redirectTo(this).listar();
	}
	
	@Get @Path("/carona/{id}/detalhe")
	public void details(Long id, Boolean extended) {
		Carona carona = dao.carregar(id);
		carona.setLinkMapa(new Mapa(carona).getEndereco());
		carona.getUsuario().getUsername();
		
		SimpleDateFormat formatdata = new SimpleDateFormat("dd/MM/yyyy HH:mm");
		carona.setDataStr(formatdata.format(carona.getData()));
		List<Usuario> passageiros = new ArrayList<Usuario>();;
		List<UsuarioProxy> proxies = new ArrayList<UsuarioProxy>();
		if(extended != null){
			passageiros = carona.getPassageiros();
		    for(Usuario passageiro : passageiros){
		    	proxies.add(new UsuarioProxy(passageiro.getNome(), passageiro.getUsername()));
		    	passageiro.getUsername();
		    }
		}
		
		CaronaWrapper cw = new CaronaWrapper(carona, proxies);
		result.use(Results.json()).withoutRoot().from(cw).include("carona").include("usuariosProxies").include("carona.usuario").include("carona.origem").include("carona.destino").serialize();
		
	}
	
	@Get @Path("/carona/{id}/mostrar")
	public Carona mostrar(Long id) {
		Carona carona = dao.carregar(id);
		carona.setLinkMapa(new Mapa(carona).getEndereco());
		return carona;
		
	}
	
	@Get @Path("/carona/oferta")
	public void ofertar() {
	}
	
	@Post @Path("/carona/oferta")
	public String trajeto(Carona carona, int vagas) {
		Trajeto trajeto = new Trajeto(carona, vagas, this.dao);
		return trajeto.getLinkTrajeto();
	}

	
	@Post @Path("/carona/{id}/confirmar")
	public void confirmar(Long id, String mensagem) {
		Carona carona = dao.carregar(id);
		byte sent = 0;// -1 - É o dono | 0 - ja pegou carona | 1 - nao tem mais vagas | 2 pegou a carona | 3 - falha na requisicao
		
		Usuario usuario = usuarioDao.carregar(usuarioWeb.getUsuario().getId());
		
		if(carona.getUsuario().getId().compareTo(usuario.getId()) == 0){
			sent = -1;
			result.use(Results.json()).withoutRoot().from(sent).serialize();
			return;
		}
		if(usuarioDao.pegouCarona(usuario, carona)){
			sent = 0;
			result.use(Results.json()).withoutRoot().from(sent).serialize();
			return;
		}
		
		else if( carona.getVagas() <= 0 ){
			sent = 1;
			result.use(Results.json()).withoutRoot().from(sent).serialize();
			return;
		}
	
		
		
		Service destinatarioService = carona.getUsuario().getServices().get(0);
		Service remetenteService = usuarioWeb.getService();
		sent = emailUtils.sentJoinNotification(carona, mensagem, destinatarioService, remetenteService);
		
		if(sent == 2){
			dao.decrementarVagas(carona);
			dao.cadastrarUsuario(usuarioWeb.getUsuario(), carona);
		}
		
		result.use(Results.json()).withoutRoot().from(sent).serialize();
	}
	
	@Get @Path("/contato")
	public void contato(){
		
	}
	
	@Post @Path("/contato/enviar")
	public void enviarContato(String mensagem){
		Service usuarioService = usuarioWeb.getService();
		boolean contactSent = emailUtils.enviarContato(usuarioService, mensagem);
		
		result.include("contactSent", contactSent);
		result.redirectTo(this).index();
		
	}
}

